/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */
package com.ykht.proj.coupon.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ykht.proj.common.core.constant.CommonConstants;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.entity.*;
import com.ykht.proj.coupon.mapper.FxShopMoneyFlowMapper;
import com.ykht.proj.coupon.service.FxMerchantAccountService;
import com.ykht.proj.coupon.service.FxShopMoneyFlowService;
import com.ykht.proj.coupon.vo.BaseSearchTimeVo;
import com.ykht.proj.coupon.vo.FxShopMoneyFlowVo;
import com.ykht.proj.coupon.vo.MoneyFlowVo;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 门店资金流水
 *
 * @author proj code generator
 * @date 2021-02-01 19:00:17
 */
@Service
@Transactional
public class FxShopMoneyFlowServiceImpl extends ServiceImpl<FxShopMoneyFlowMapper, FxShopMoneyFlow> implements FxShopMoneyFlowService {

	@Resource
	private FxShopMoneyFlowMapper fxShopMoneyFlowMapper;

	@Resource
	private FxMerchantAccountService fxMerchantAccountService;

	/**
	 * 服务员提现
	 *
	 * @param withdrawalType 提现类型：1  微信提现  2支付宝   3银行卡
	 * @param companyId      公司ID
	 * @param brandId        品牌ID
	 * @param shopId         门店ID
	 * @param waiterId       服务员id
	 * @param money          提现金额
	 * @param balance        服务员 当前提现后 的余额
	 * @param shopBalance    服务员 当前提现后门店 的余额
	 * @param status         提现状态：0成功1余额不足2风控限制
	 * @param batchNumber    提现批次编号
	 */
	@Override
	public FxWithdrawal addWaiterWithdrawal(Long withdrawalType, Long companyId, Long brandId, Long shopId,
									Long waiterId, BigDecimal money, BigDecimal balance, BigDecimal shopBalance, Integer status, String batchNumber) {
		Long userId = SecurityUtils.getUserId();
		// 先给服务员提现
		FxWithdrawal fxWithdrawal1 = new FxWithdrawal();
		fxWithdrawal1.setBatchNumber(batchNumber);
		fxWithdrawal1.setOrderNumber(DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.random(6, "0123456789"));
		fxWithdrawal1.setWithdrawalType(withdrawalType);
		fxWithdrawal1.setCompanyId(companyId);
		fxWithdrawal1.setBrandId(brandId);
		fxWithdrawal1.setShopId(shopId);
		fxWithdrawal1.setWaiterId(waiterId);
		fxWithdrawal1.setMoney(money);
		fxWithdrawal1.setBalance(balance);
		fxWithdrawal1.setShopBalance(shopBalance);
		fxWithdrawal1.setStatus(status);
		fxWithdrawal1.setCreateTime(LocalDateTime.now());
		fxWithdrawal1.setCreateUser(userId);
		fxWithdrawal1.setDelFlag(0);
		fxWithdrawal1.insert();
		return fxWithdrawal1;
		// 在扣门店余额
//		FxShopMoneyFlow fxShopMoneyFlow = new FxShopMoneyFlow();
//		fxShopMoneyFlow.setBatchNumber(batchNumber);
//		fxShopMoneyFlow.setShopId(shopId);
//		fxShopMoneyFlow.setCompanyId(companyId);
//		fxShopMoneyFlow.setBrandId(brandId);
//		fxShopMoneyFlow.setFlowType(1);
//		fxShopMoneyFlow.setFlowMoney(money);
//		fxShopMoneyFlow.setWithdrawalId(fxWithdrawal1.getId());
//		fxShopMoneyFlow.setTradeId(DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.random(6, "0123456789"));
//		fxShopMoneyFlow.setWaiterId(waiterId);
//		fxShopMoneyFlow.setCreateTime(LocalDateTime.now());
//		fxShopMoneyFlow.setCreateUser(userId);
//		fxShopMoneyFlow.setDelFlag(0);
//		this.save(fxShopMoneyFlow);
	}

	@Override
	public void addShopMoneyFlow(List<FxWithdrawal> list) {
		Long userId = SecurityUtils.getUserId();
		List<FxShopMoneyFlow> shopMoneyFlowList = list.stream().map(o->{
			FxShopMoneyFlow fxShopMoneyFlow = new FxShopMoneyFlow();
			fxShopMoneyFlow.setBatchNumber(o.getBatchNumber());
			fxShopMoneyFlow.setShopId(o.getShopId());
			fxShopMoneyFlow.setCompanyId(o.getCompanyId());
			fxShopMoneyFlow.setBrandId(o.getBrandId());
			fxShopMoneyFlow.setFlowType(1);
			fxShopMoneyFlow.setFlowMoney(o.getMoney());
			fxShopMoneyFlow.setWithdrawalId(o.getId());
			fxShopMoneyFlow.setTradeId(DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.random(6, "0123456789"));
			fxShopMoneyFlow.setWaiterId(o.getWaiterId());
			fxShopMoneyFlow.setCreateTime(LocalDateTime.now());
			fxShopMoneyFlow.setCreateUser(userId);
			fxShopMoneyFlow.setDelFlag(0);
			return fxShopMoneyFlow;
		}).collect(Collectors.toList());
		this.saveBatch(shopMoneyFlowList);
	}

	@Override
	public BigDecimal shopBalance(Long shopId, BaseSearchTimeVo timeVo) {
		List<FxShopMoneyFlow> list = fxShopMoneyFlowMapper.selectList(Wrappers.lambdaQuery(FxShopMoneyFlow.class)
				.eq(FxShopMoneyFlow::getShopId,shopId)
				.ge(timeVo.getStartTime()!=null,FxShopMoneyFlow::getCreateTime,timeVo.getStartTime())
				.le(timeVo.getEndTime()!=null,FxShopMoneyFlow::getCreateTime,timeVo.getEndTime()));
		//0充值1提现
		BigDecimal in = list.stream().filter(o->o.getFlowType()==0).map(FxShopMoneyFlow::getFlowMoney).reduce(BigDecimal.ZERO,BigDecimal::add);
		BigDecimal out = list.stream().filter(o->o.getFlowType()==1).map(FxShopMoneyFlow::getFlowMoney).reduce(BigDecimal.ZERO,BigDecimal::add);

//		return fxShopMoneyFlowMapper.shopBalance(shopId,timeVo);
		return in.subtract(out);
	}

	@Override
	public BigDecimal shopBalanceFast(Long shopId, BaseSearchTimeVo timeVo) {
		BigDecimal balance = fxShopMoneyFlowMapper.shopBalance(shopId, timeVo);
		return balance == null ? BigDecimal.valueOf(0) : balance;
	}

	@Override
	public R findPage(Page page, FxShopMoneyFlowVo fxShopMoneyFlowVo) {
		List<FxShopMoneyFlow> list = this.baseMapper.findPage(page,fxShopMoneyFlowVo);
		return R.ok(page.setRecords(list));
	}

	@Override
	public BigDecimal rechargeMoney(Long id) {
		return this.baseMapper.rechargeMoney(id);
	}

	@Override
	public R getShopPage(Page page, FxShopMoneyFlowVo vo) {
		List<FxShopMoneyFlowVo> list = this.baseMapper.getShopPage(page,vo);
		return R.ok(page.setRecords(list));
	}

    @Override
    public List<FxShopMoneyFlowVo> show(CnBrand data) {
        return this.baseMapper.rechargeRecord(data);
    }

	@Override
	public FxShopMoneyFlowVo rechargeItem(CnBrand data,FxShopMoneyFlow fxShopMoneyFlow) {
		FxShopMoneyFlowVo fxShopMoneyFlowVo = this.baseMapper.queryMoneyByOrderId(fxShopMoneyFlow.getOrderId());
		List<FxShopMoneyFlowVo> fxShopMoneyFlowVos = this.baseMapper.rechargeItem(data, fxShopMoneyFlow);
		fxShopMoneyFlowVo.setFxShopMoneyFlowVos(fxShopMoneyFlowVos);
		return fxShopMoneyFlowVo;
	}

	/**
	 * 获取门店余额
	 *
	 * @param shopId
	 * @return
	 */
	@Override
	public FxShopMoneyFlowVo getShopBalance(Long shopId) {
		return fxShopMoneyFlowMapper.getShopBalance(shopId);
	}

	@Override
	public List<FxShopMoneyFlowVo> showCnShop(CnShop cnShop) {
		return this.baseMapper.showCnShop(cnShop);
	}

	/**
	 * 充值 b端账户表
	 *
	 * @param fxShopMoneyFlow 门店资金流水
	 * @return R
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addChargeMerchantAccount(FxShopMoneyFlow fxShopMoneyFlow) {
	/*	FxMerchantAccount account = fxMerchantAccountService.getOne(Wrappers.lambdaQuery(FxMerchantAccount.class)
				.eq(FxMerchantAccount::getType, fxShopMoneyFlow.getMerchantType())
				.eq(FxMerchantAccount::getTatId, fxShopMoneyFlow.getMerchantType().equals(1)
						? fxShopMoneyFlow.getCompanyId() : fxShopMoneyFlow.getMerchantType().equals(2)
						? fxShopMoneyFlow.getBrandId() : fxShopMoneyFlow.getShopId()));
		// 充值账号没有就创建一个
		FxMerchantAccount fxMerchantAccount = new FxMerchantAccount();
		fxMerchantAccount.setType(fxShopMoneyFlow.getMerchantType());
		if (fxShopMoneyFlow.getMerchantType().equals(1)){
			fxMerchantAccount.setAccount(String.format(CommonConstants.ACCONCE_COMPANY_FORMAT, fxShopMoneyFlow.getCompanyId()));
			fxMerchantAccount.setTatId(fxShopMoneyFlow.getCompanyId());
		} else if (fxShopMoneyFlow.getMerchantType().equals(2)){
			fxMerchantAccount.setAccount(String.format(CommonConstants.ACCONCE_BRAND_FORMAT, fxShopMoneyFlow.getBrandId()));
			fxMerchantAccount.setTatId(fxShopMoneyFlow.getBrandId());
		} else if (fxShopMoneyFlow.getMerchantType().equals(3)){
			fxMerchantAccount.setAccount(String.format(CommonConstants.ACCONCE_SHOP_FORMAT, fxShopMoneyFlow.getShopId()));
			fxMerchantAccount.setTatId(fxShopMoneyFlow.getShopId());
		}
		if (null == account) {
			fxMerchantAccount.setBalance(BigDecimal.ZERO);
			fxMerchantAccount.setBalanceTotal(BigDecimal.ZERO);
			fxMerchantAccount.setBalanceFrozen(BigDecimal.ZERO);
			fxMerchantAccount.setWithdrawal(BigDecimal.ZERO);
			fxMerchantAccount.setConsumeMoney(BigDecimal.ZERO);
			fxMerchantAccount.setChargeTotal(BigDecimal.ZERO);
			fxMerchantAccount.setCreateUser(SecurityUtils.getUserId());
			fxMerchantAccount.setCreateTime(LocalDateTime.now());
			fxMerchantAccountService.save(fxMerchantAccount);
		}
		fxMerchantAccountService.updateMerchantAccount(fxMerchantAccount.getType(), fxMerchantAccount.getTatId(),
				fxShopMoneyFlow.getFlowMoney(), fxShopMoneyFlow.getFlowMoney(), null, null,
				null, fxShopMoneyFlow.getFlowMoney(), SecurityUtils.getUserId());

		// 添加充值记录
		fxShopMoneyFlow.setBalanceMoney(null == account ? fxShopMoneyFlow.getFlowMoney() : account.getBalance().add(fxShopMoneyFlow.getFlowMoney()));
		this.save(fxShopMoneyFlow);*/
	}

	/**
	 * 分页查询 充值记录表
	 *
	 * @param page              分页对象
	 * @param fxShopMoneyFlowVo 充值记录表
	 * @return
	 */
	@Override
	public IPage<FxShopMoneyFlowVo> getChargeRecordPage(Page page, FxShopMoneyFlowVo fxShopMoneyFlowVo) {
		return fxShopMoneyFlowMapper.getChargeRecordPage(page, fxShopMoneyFlowVo);
	}

	@Override
	public Page<MoneyFlowVo> chargeRecordPage(Page page, MoneyFlowVo moneyFlowVo) {
		return fxShopMoneyFlowMapper.chargeRecordPage(page,moneyFlowVo);
	}

	@Override
	public List<MoneyFlowVo> chargeRecordPage(MoneyFlowVo moneyFlowVo) {
		return fxShopMoneyFlowMapper.chargeRecordPage(moneyFlowVo);
	}
}
